/*
 * Copyright (c) kecp
 * Build on May 07, 2010
 */

package LBS;

import Tool.Debugger;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.*;
import org.json.me.JSONException;
import org.json.me.JSONObject;

/**
 * translate the cell_id to location using Ericsson Location Service.
 * Note that the mobile is  requested to have a network connection.
 * @author kecp
 */
public class EricssonLBS implements LocationService{
    Location locKeep = null;
    Cell cellKeep = null;
    String appKey = "82cqQCN8YKW85Gwp1a9pd6xScHgEQb4F5NAwGAIF";
    

    /**
      * parseJSON
      * For JSON support we are using org.json.me
      * The JSON package can be downloaded from here:
      *  <a href="http://www.json.org/java/org.json.me.zip<br />
    " title="www.json.org/java/org.json.me.zip<br />
    ">www.json.org/java/org.json.me.zip<br />
    </a>  */
     public Location parseJSON(String jsonString) {
         Location loc = new Location();

         try {
            JSONObject o = new JSONObject(jsonString);
            JSONObject pos = o.getJSONObject("position");
            loc.setLon( pos.getString("longitude"));
            loc.setLat(  pos.getString("latitude") );
            loc.setAccuracy( pos.getString("accuracy"));
            loc.setName(pos.optString("name"));

            } catch(JSONException e) {
            e.printStackTrace();
            Debugger.addDebugInfo(e, "exception when parse LBS response");
            return null;
        }
         return loc;
     }

   static public byte[] getHttp(String url) throws IOException {

      HttpConnection c = null;
      InputStream is = null;
      byte[] data = null;

      try {
       c = (HttpConnection)Connector.open(url);
       int rc = c.getResponseCode();

       // handle the HTTP response codes used by the API
       if(rc!=HttpConnection.HTTP_OK) {
            switch(rc) {
            case HttpConnection.HTTP_NO_CONTENT:
             throw new IOException("The cell could not be "+
                    "found in the database");
            case HttpConnection.HTTP_BAD_REQUEST:
             throw new IOException("Check if some parameter "+
                    "is missing or misspelled");
            case HttpConnection.HTTP_UNAUTHORIZED:
             throw new IOException("Make sure the API key is "+
                    "present and valid");
            case HttpConnection.HTTP_FORBIDDEN:
             throw new IOException("You have reached the limit "+
                    "for the number of requests per day. The maximum "+
                    "number of requests per day is currently 500.");
            case HttpConnection.HTTP_NOT_FOUND:
             throw new IOException("The cell could not be found "+
                             "in the database");
            default:
             throw new IOException("HTTP response code: " + rc);
            }
       }

       is = c.openInputStream();

       int actual = 0;
       int len = (int)c.getLength();
       if(len>0) {
            int bytesread = 0 ;
            // the server returned a length so we can allocate
            // a byte array directly
            data = new byte[len];
            // loop until there is nothing more to read or
            // until buffer is full
            while((bytesread != len) && (actual != -1)) {
             actual = is.read(data, bytesread, len - bytesread);
             bytesread += actual;
            }
       } else {
            // the server is not returning a length
            // so we need a ByteArrayOutputStream
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            // create a 256 bytes read buffer to
            // improve reading performance
            byte buf[] = new byte[256];
            // loop for as long as we get data from the server
            // and add it to the output stream
            while((actual = is.read(buf, 0, 256))!=-1) {
             bos.write(buf, 0, actual);
            }
            bos.flush();
            data = bos.toByteArray();
       }
      } catch (ClassCastException e) {
       throw new IllegalArgumentException("Not an HTTP URL");
      } finally {
       try { if (c != null) c.close(); } catch(IOException e) {};
       try { if (is != null) is.close(); } catch(IOException e) {};
      }
      return data;
     }

    public Location getLocation(String cellid, String mnc, String mcc, String lac, int timeOut) {
        StringBuffer sb = new StringBuffer("http://cellid.labs.ericsson.net/json/lookup?");
        sb.append("cellid="+cellid).append("&mnc="+mnc).append("&mcc="+mcc).append("&lac="+lac)
                .append("&key="+ appKey);
        String request = sb.toString(),response;
        Tool.Debugger.addDebugInfo(request);
        Tool.Debugger.addDebugInfo("cellid request to ericsson");
        Location loc = null;
        try {
            byte[] data = getHttp(request);
            String str = new String(data);
            Tool.Debugger.addDebugInfo(str);
            loc = parseJSON( str );
            if(loc != null)
            Tool.Debugger.addDebugInfo("Location: " +loc.toString());
            //locKeep = loc;
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
        sb = null;
        return loc;
    }

    public Location getPrevLocation() {
       return locKeep;
    }

    static public Location testEriLBS() {
        Location loc;
        EricssonLBS eriLbs = new EricssonLBS();
        Cell cell = new Cell();
        cell.updateNetworkInfo();

//         cell.cell_id =  "4008701";
//         cell.mcc = "234";
//         cell.mnc = "10";
//         cell.lac = "0";
            loc = eriLbs.getLocation(cell);
       // loc = eriLbs.getLocation(cell.cell_id, cell.mnc, cell.mcc, cell.lac, 1000);
      //  String.format();
        return loc;
    }

    public Location getLocation(Cell cell) {
        return getLocation(cell.cell_id,cell.mnc,cell.mcc,cell.lac, 1000);
    }

    public Location getCurLocation() {
        //取得当前基站信息
        Cell cell = new Cell();
        cell.updateNetworkInfo();
        
        if( cell.isAvailable() == false )
            return null;

        //检查是否跟前一个查询的基站一致
        if( locKeep != null && cellKeep != null && cellKeep.isEquals(cell) ) {
            return locKeep;
        }
//
//        cell.cell_id =  "0008c257";
//        cell.mcc = "240";
//        cell.mnc = "08";
//        cell.lac = "017c";

        //查询并保存新的基站信息
        Location newLoct = getLocation( cell );
        if(newLoct != null) {
            locKeep = newLoct;
            cellKeep = cell;
        }

        return locKeep;
    }
}
